/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "decode_interceptor_avif.h"
#include "securec.h"

namespace ImageKnifePro {

DecodeInterceptorAvif::DecodeInterceptorAvif()
{
    name = "Default DecodeInterceptor Avif";
}

bool DecodeInterceptorAvif::Resolve(std::shared_ptr<ImageKnifeTask> task)
{
    auto taskInternal = std::dynamic_pointer_cast<ImageKnifeTaskInternal>(task);
    IMAGE_KNIFE_CHECK_RETURN(taskInternal == nullptr, false);

    auto fileTypeInfo = task->GetFileTypeInfo();
    if (fileTypeInfo == nullptr) {
        task->EchoError("Unknown FileType Info");
        return false;
    }

    if (fileTypeInfo->format != ImageFormat::AVIF) {
        return false;
    }

    if (task->product.imageBuffer == nullptr) {
        task->EchoError("Empty ImageBuffer");
        return false;
    }
    return Decode(taskInternal);
}

bool DecodeInterceptorAvif::Decode(std::shared_ptr<ImageKnifeTaskInternal> task)
{
    std::unique_ptr<ImageKnifeDecoderAvif> decoderPtr;
    ImageKnifeDecoderAvif *decoder = task->GetAvifDecoder();
    if (decoder == nullptr) {
        // 没有复用的decoder source，尝试创建一个
        decoderPtr = std::make_unique<ImageKnifeDecoderAvif>();
        std::string errorInfo = decoderPtr->Init(task->product.imageBuffer.get(), task->product.imageLength);
        if (!errorInfo.empty()) {
            task->EchoError(errorInfo);
            return false;
        }
        decoder = decoderPtr.get();
    }

    uint32_t frameCount = decoder->GetFrameCount();
    IMAGE_KNIFE_CHECK_RETURN(frameCount < 1, false, "avif decoder image count incorrect");

    auto request = task->GetImageKnifeRequestInternal();
    IMAGE_KNIFE_CHECK_RETURN(request == nullptr, false);
    auto option = request->GetImageKnifeOption();
    IMAGE_KNIFE_CHECK_RETURN(option == nullptr, false);

    decoder->SetAllocationMode(option->allocationMode);
    decoder->SetDesiredImageSize(task->GetDesiredImageSize());

    if (task->IsFrameDecodeMode()) {
        OH_PixelmapNative *pixelmap = nullptr;
        std::string errorInfo = decoder->DecodeFrame(task->GetDecodeFrameIndex(), &pixelmap);
        if (!errorInfo.empty()) {
            task->EchoError(errorInfo);
            return false;
        }

        task->product.imageData = std::make_shared<ImageData>(pixelmap);
    } else {
        // 批量解码所有帧
        OH_PixelmapNative **pixelmapList = new OH_PixelmapNative *[frameCount];
        (void)memset_s(pixelmapList, sizeof(OH_PixelmapNative *) * frameCount, 0,
                       sizeof(OH_PixelmapNative *) * frameCount);

        // 如果中途出现错误，imageData析构pixelmapList
        auto imageData = std::make_shared<ImageData>(pixelmapList, decoder->GetDelayTimeList(), frameCount);
        for (int i = 0; i < frameCount; i++) {
            std::string errorInfo = decoder->DecodeFrame(i, &pixelmapList[i]);
            if (!errorInfo.empty()) {
                task->EchoError(errorInfo);
                return false;
            }
        }

        task->product.imageData = imageData;
    }

    return true;
}

}
